package yb.ecp.fast.infra.annotation;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import yb.ecp.fast.feign.AuthClient;
import yb.ecp.fast.infra.constants.AccessLabel;
import yb.ecp.fast.infra.constants.ErrorCode;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by john on 2017/4/22.
 */
@Aspect
@Component
public class FastAccessGrantAspect {

    @Autowired
    private AuthClient authClient;

    private ActionResult<Object> actionResult(ErrorCode code) {
        return new ActionResult<>(code.getCode(), code.getDesc());
    }


    @Around(value = "@annotation(FastMappingInfo) && @annotation(fastMappingInfo)")
    public Object accessCheck(ProceedingJoinPoint proceedingJoinPoint,
                              FastMappingInfo fastMappingInfo)
            throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String accessClient = request.getHeader("x-access-client");
        String userId = request.getHeader("x-user-id");
        String appId = request.getHeader("x-app-id");

        AccessLabel accesslevel = AccessLabel.DenyAll;
        if ("oauth2".equals(accessClient)) {
            accesslevel = AccessLabel.Oauth2;
        } else if ("gateway".equals(accessClient)) {
            accesslevel = AccessLabel.Client;
        } else if (StringUtil.isNullOrEmpty(accessClient)) {
            //let's assume this is only for test in trust area.
            accesslevel = AccessLabel.FullTrusted;
        }

        //访问权限小于函数权限，则不允许访问
        if (fastMappingInfo.actionLevel() > accesslevel.getLevelNum()) {
            return actionResult(ErrorCode.AccessDenied);
        }
        // 内部服务访问，不再做needLogin的校验
        if (AccessLabel.FullTrusted.equals(accesslevel)) {
            return proceedingJoinPoint.proceed();
        }


        boolean needLogin = fastMappingInfo.needLogin() || fastMappingInfo.code() > 0;
        if (needLogin && StringUtil.isNullOrSpace(userId)) {
            return actionResult(ErrorCode.NeedLogin);
        }


        if (fastMappingInfo.code() == 0) {
            return proceedingJoinPoint.proceed();
        }

        ActionResult actionResult;
        if (StringUtil.isNullOrEmpty(appId)) {
            actionResult = authClient.checkAuthCode(userId, fastMappingInfo.code());
        } else {
            //app目前没还有权限,暂时不验证
            //actionResult = appClient.checkAuthCode(userId, fastMappingInfo.code());
            actionResult = actionResult(ErrorCode.Success);
        }
        if (actionResult.getCode() != 0) {
            return actionResult;
        }

        return proceedingJoinPoint.proceed();

    }
}
